#include <iostream>
using namespace std;
#include "ta234com.h"
#include <math.h>

TA234Nodo::TA234Nodo()
{
	numitem=1;
	itIz=itMe=itDe=0;
	eshoja=true;
}

TA234Nodo::TA234Nodo(const TA234Nodo& a)
{
	itIz=a.itIz;
	itDe=a.itDe;
	itMe=a.itMe;
	hijoDe=a.hijoDe;
   	hijoMeDe=a.hijoMeDe;
   	hijoMeIz=a.hijoMeIz;
   	hijoIz=a.hijoIz;  
   	numitem=a.numitem;
   	eshoja=a.eshoja;
}

TA234Nodo::~TA234Nodo(){}

TA234Nodo&
TA234Nodo::operator=(const TA234Nodo& a)
{
	if (this!=&a)
	{
		itIz=a.itIz;
		itDe=a.itDe;
		itMe=a.itMe;
		hijoDe=a.hijoDe;
		hijoMeDe=a.hijoMeDe;
		hijoMeIz=a.hijoMeIz;
		hijoIz=a.hijoIz;
		numitem=a.numitem;	
		eshoja=a.eshoja;
	}
	return *this;
}

bool 
TA234Nodo::operator==(const TA234Nodo& a) const
{
	return(true);
}
//======================================================================

TA234Com::TA234Com()
{
	raiz=NULL;		
}

TA234Com::TA234Com(const TA234Com& a)
{
    if (a.raiz!=NULL)
    {
    	raiz=new TA234Nodo(*a.raiz);	
    }
    else
    {
    	raiz=NULL;
    }	
	
}

TA234Com::~TA234Com()
{
	TA234Nodo* aux;
	if (raiz!=NULL)
    {
		aux = raiz;
		raiz = NULL;
    	delete aux;	
    }
    raiz=NULL;	
}

TA234Com&
TA234Com::operator=(const TA234Com& a)
{
	if (this!=&a)
	{
		if(raiz!=NULL) delete (raiz);
		if (a.raiz!=NULL)
		{
			raiz=new TA234Nodo(*a.raiz);	
		}
		else
		{
			raiz=NULL;
		}
	}	
	return *this;
}

bool 
TA234Com::operator==(const TA234Com& a) const 
{
	bool ret=true;

	ret = (Niveles() == a.Niveles());
		
	return ret;
}

bool 
TA234Com::EsVacio() const
{
	return(raiz==NULL);
}

bool 
TA234Com::Insertar(const TComplejo& c)
{
	bool ret=true;
	TA234Nodo* raiz;
	bool parar = false;

	raiz = this->raiz;
	
	if (this->raiz==NULL)
	{
		this->raiz=new TA234Nodo();
		this->raiz->itIz=c;
		parar=true;
	}
	else
	{
		if (raiz->numitem==3)
		{
			raiz->DivideRaiz();
		}
		
	}
	
	while (!parar)
	{
		if (raiz->eshoja)
		{
			if (raiz->numitem==1)
			{
				if (raiz->itIz==c)
				{
					raiz->numitem--;
					parar=true;
				}
				
				else if (raiz->itIz>c)
				{
					raiz->itMe=raiz->itIz;
					raiz->itIz=c;
				}
				else
				{
					raiz->itMe=c;
				}
			}
			else if (raiz->numitem==2)
			{
				if (raiz->itIz==c || raiz->itMe==c)
				{
					raiz->numitem--;
					parar=true;
				}
				
				else if (raiz->itIz>c)
				{
					raiz->itDe=raiz->itMe;
					raiz->itMe=raiz->itIz;
					raiz->itIz=c;
				}
				else if (raiz->itMe>c)
				{
					raiz->itDe=raiz->itMe;
					raiz->itMe=c;
				}
				else 
				{
					raiz->itDe=c;
				}
			}
			raiz->numitem++;
			parar = true;
		}
		else
		{
			if (raiz->itIz==c)
			{
				parar=true;
			}
			else if (c<raiz->itIz)
			{
				if (raiz->hijoIz.raiz->numitem==3)
				{
					if (raiz->numitem==1)
					{
						raiz->Divide2(1);
					}
					else if (raiz->numitem==2)
					{
						raiz->Divide3(1);
					}
					
					if (c>raiz->itIz)
					{
						raiz=raiz->hijoMeIz.raiz;
					}
					else
					{
						raiz=raiz->hijoIz.raiz;
					}
				}
				else
				{
					raiz=raiz->hijoIz.raiz;
				}	
			}
			else if (raiz->numitem>=2 && c==raiz->itMe)
			{
				parar=true;
			}
			
			else if ((raiz->numitem==1 && c>raiz->itIz) || (raiz->numitem>=2 && c<raiz->itMe))
			{
				if (raiz->hijoMeIz.raiz->numitem==3)
				{
					if (raiz->numitem==1)
					{
						raiz->Divide2(2);
					}
					else if (raiz->numitem==2)
					{
						raiz->Divide3(2);
					}
					if (c>raiz->itMe)
					{
						raiz=raiz->hijoMeDe.raiz;
					}
					else
					{
						raiz=raiz->hijoMeIz.raiz;
					}
				}
				else
				{
					raiz=raiz->hijoMeIz.raiz;
				}
			}
			else if (raiz->numitem==2 && c>raiz->itMe)
			{
				if (raiz->hijoMeDe.raiz->numitem==3)
				{
					raiz->Divide3(3);
					if (c>raiz->itDe)
					{
						raiz=raiz->hijoDe.raiz;
					}
					else
					{
						raiz=raiz->hijoMeDe.raiz;
					}
				}
				else
				{
					raiz=raiz->hijoMeDe.raiz;
				}
			}
		}
	}
	
	return ret;
}

bool 
TA234Com::Buscar(const TComplejo& c) const
{
	bool ret=false;
	if (raiz!=NULL )
	{		
		if(c<raiz->itIz)//menor que el primero 
		{
			ret=raiz->hijoIz.Buscar(c);
		}
		else if (raiz->numitem>=1 && raiz->itIz==c)//es el izquierdo 
		{
			ret=true;
		}
		else if ((raiz->numitem==1 && c>raiz->itIz) || (raiz->numitem>=2 && c<raiz->itMe))//mayor que el izquierdo y menor que el medio
		{
			ret=raiz->hijoMeIz.Buscar(c);
		}
		else if ( raiz->numitem>=2 && c==raiz->itMe)//igual al medio
		{
			ret=true;
		}
		else if ((raiz->numitem>=3 && c<raiz->itDe) || (raiz->numitem==2 && c>raiz->itMe))//menor que el derecho
		{
			ret=raiz->hijoMeDe.Buscar(c);
		}
		else if (raiz->numitem>=3 && c==raiz->itDe)//es el derecho
		{
			ret=true;
		}
		else if (raiz->numitem>=3 && c>raiz->itDe)//mayor que todos
		{
			ret=raiz->hijoDe.Buscar(c);
		}
	}
	
	return ret;
}

int 
TA234Com::Altura() const
{
	int ret=0;
	
	if (raiz==NULL)
	{
		ret=0;
	}
	else
	{
		ret=1+raiz->hijoIz.Altura();
	}
	return ret;	
}

int 
TA234Com::Nodos() const
{
	int ret=0;
	
	if (raiz != NULL)
	{
		ret ++;
		if (!raiz->eshoja)
		{
			if (raiz->numitem>0)
			{
				ret+=raiz->hijoIz.Nodos();
				ret+=raiz->hijoMeIz.Nodos();
			}
			if (raiz->numitem>1)
			{
				ret+=raiz->hijoMeDe.Nodos();
			}
			if (raiz->numitem>2)
			{
				ret+=raiz->hijoDe.Nodos();
			}
		}
	}

	return ret;
}

int 
TA234Com::NodosHoja() const
{
	int ret=0;
	
	if (raiz != NULL)
	{
		if (!raiz->eshoja)
		{
			if (raiz->numitem>0)
			{
				ret+=raiz->hijoIz.NodosHoja();
				ret+=raiz->hijoMeIz.NodosHoja();
			}
			if (raiz->numitem>1)
			{
				ret+=raiz->hijoMeDe.NodosHoja();
			}
			if (raiz->numitem>2)
			{
				ret+=raiz->hijoDe.NodosHoja();
			}	
		}
		else
		{
			ret++;
		}
	}


	return ret;

}

TListaCom
TA234Com::Niveles() const 
{
	TListaCom ret;
	if (this->raiz!=NULL)
	{
		NivelesAux(ret);
	}
	return ret;
	
}

void
TA234Com::NivelesAux(TListaCom& l)const 
{
	TA234Cola c;
	TA234Com *aux;
	
	c.Encolar(this);
	
	while (!c.Esvacia())
	{
		aux=c.Desencolar();
		if (aux != NULL)
		{
			l.InsCola(aux->raiz->itIz);
			
			if (!aux->raiz->eshoja && aux->raiz->hijoIz.raiz != NULL)
			{
				c.Encolar(&aux->raiz->hijoIz);
				c.Encolar(&aux->raiz->hijoMeIz);
			}
			if (aux->raiz->numitem>1)
			{
				l.InsCola(aux->raiz->itMe);
				
				if (!aux->raiz->eshoja && aux->raiz->hijoMeDe.raiz != NULL)
				{
					c.Encolar(&aux->raiz->hijoMeDe);	
				}
				if (aux->raiz->numitem>2)
				{
					l.InsCola(aux->raiz->itDe);
					
					if (!aux->raiz->eshoja && aux->raiz->hijoDe.raiz != NULL)
					{
						c.Encolar(&aux->raiz->hijoDe);
					}
					
				}
			}
		}
	}	
}

TListaCom
TA234Com::Inorden() const 
{
	TListaCom ret;
	
	InordenAux(ret);
	
	return ret;
}

void 
TA234Com::InordenAux(TListaCom& l)const 
{
	if (raiz!=NULL)
	{
		if (raiz->eshoja)
		{
			l.InsCola(raiz->itIz);
			if (raiz->numitem>1)
			{
				l.InsCola(raiz->itMe);
				if (raiz->numitem>2)
				{
					l.InsCola(raiz->itDe);
				}
			}	
		}
		else
		{
			raiz->hijoIz.InordenAux(l);	
			l.InsCola(raiz->itIz);
			raiz->hijoMeIz.InordenAux(l);
			if (raiz->numitem>1)
			{
				l.InsCola(raiz->itMe);
				raiz->hijoMeDe.InordenAux(l);
				if (raiz->numitem>2)
				{
					l.InsCola(raiz->itDe);
					raiz->hijoDe.InordenAux(l);
				}
			}	
		}
	}
}

bool 
TA234Com::Borrar(const TComplejo &b)
{
	bool ret=false;
	TA234Nodo* raiz;
	bool parar = false;
	TComplejo c = b;
	TComplejo aux;
	
	raiz = this->raiz;
	
	if (this->raiz==NULL)
	{
		ret = false;
		parar = true;
	}
	else
	{
		if (raiz->numitem==1 && !raiz->eshoja && raiz->hijoIz.raiz->numitem==1 && raiz->hijoMeIz.raiz->numitem==1)
		{
			raiz->Combina2();
		}
	}

	while (!parar)
	{
		
		if (raiz->eshoja)
		{
			if (raiz->numitem == 1 && raiz->itIz == c)
			{
				raiz->itIz = 0;
				raiz->numitem--;
				parar = true;
				ret = true;
				delete this->raiz;
				this->raiz=NULL;
			}
			else if (raiz->numitem>=1 && raiz->itIz==c)
			{
				raiz->numitem--;
				raiz->itIz = raiz->itMe;
				raiz->itMe = raiz->itDe;
				parar = true;
				ret = true;
			}
			else if (raiz->numitem>=2 && raiz->itMe==c)
			{
				raiz->numitem--;
				raiz->itMe = raiz->itDe;
				parar = true;
				ret = true;
			}
			else if (raiz->numitem>=3 && raiz->itDe == c)
			{
				raiz->numitem--;
				raiz->itDe = 0;
				parar = true;
				ret = true;
			}
			else
			{
				parar = true;
				ret = false;
			}
		}
		else
		{
			if (raiz->itIz==c)	//Igual al izquierdo 
			{
				raiz->itIz = raiz->MayorIzquierda(0, c);

				if (raiz->hijoIz.raiz->numitem == 1)
				{
					raiz->Reestructurar(1, raiz);
				}
				else
				{
					raiz = raiz->hijoIz.raiz;
				}
			}
			else if (c<raiz->itIz) //X hijo izquierdo
			{
				if (raiz->hijoIz.raiz->numitem==1)
				{
					raiz->Reestructurar(1, raiz);
				}
				else
				{
					raiz=raiz->hijoIz.raiz; //Avanzamos por hijo izquierdo
				}	
			}
			else if (raiz->numitem>=2 && c==raiz->itMe) //Igual al medio
			{
				raiz->itMe = raiz->MayorIzquierda(1, c);

				if (raiz->hijoMeIz.raiz->numitem == 1)
				{
					raiz->Reestructurar(2,raiz);
				}
				else
				{
					raiz = raiz->hijoMeIz.raiz;
				}
			}
			else if ((raiz->numitem==1 && c>raiz->itIz) || (raiz->numitem>=2 && c<raiz->itMe)) //X hijo MeIz
			{
				if (raiz->hijoMeIz.raiz->numitem==1)
				{
					raiz->Reestructurar(2,raiz);
				}
				else
				{
					raiz=raiz->hijoMeIz.raiz; //Avanzamos MeIz
				}
			}
			else if (raiz->numitem==3 && c==raiz->itDe) //Igual al derecho
			{
				raiz->itDe = raiz->MayorIzquierda(2, c);
				if (raiz->hijoMeDe.raiz->numitem==1)
				{
					raiz->Reestructurar(3,raiz);
				}
				else
				{
					raiz = raiz->hijoMeDe.raiz;
				}
			}		
			else if ((raiz->numitem==2 && c>raiz->itMe) || (raiz->numitem==3 && c<raiz->itDe)) //X hijo MeDe
			{
				if (raiz->hijoMeDe.raiz->numitem==1)
				{
					raiz->Reestructurar(3,raiz);
				}
				else
				{
					raiz=raiz->hijoMeDe.raiz;
				}
			}
			else if (raiz->numitem==3 && c>raiz->itDe) //Hijo derecho
			{
				if (raiz->hijoDe.raiz->numitem==1)
				{
					raiz->Reestructurar(4,raiz);
				}
				else
				{
					raiz=raiz->hijoDe.raiz;
				}
			}
			else
			{
				cout <<"ERROR" <<endl;
			}
		}	
	}

	return ret;
}

void
TA234Nodo::DivideRaiz()
{
	TA234Nodo *a;
	
	a = this->hijoIz.raiz;

	this->hijoIz.raiz= new TA234Nodo;
	this->hijoIz.raiz->itIz=this->itIz;
	this->hijoIz.raiz->hijoIz.raiz=a;
	this->hijoIz.raiz->hijoMeIz.raiz=this->hijoMeIz.raiz;;
	
	this->hijoMeIz.raiz=new TA234Nodo;
	this->hijoMeIz.raiz->itIz=this->itDe;
	this->hijoMeIz.raiz->hijoIz.raiz=this->hijoMeDe.raiz;
	this->hijoMeIz.raiz->hijoMeIz.raiz=this->hijoDe.raiz;
	
	this->itIz=this->itMe;
	this->hijoMeDe.raiz=this->hijoDe.raiz=NULL;
	this->itMe=this->itDe=0;
	this->numitem=1;
	this->eshoja=false;
	
	if (this->hijoIz.raiz->hijoIz.raiz!=NULL)
	{
		this->hijoIz.raiz->eshoja=this->hijoMeIz.raiz->eshoja=false;
	}
	
}

void
TA234Nodo::Divide2(const int num)
{
	TA234Nodo* aux;
	
	if (num==1)
	{
		aux=this->hijoIz.raiz;
		this->itMe=this->itIz;
		this->itIz=aux->itMe;
		this->hijoMeDe.raiz=this->hijoMeIz.raiz;
		
		this->hijoMeIz.raiz=new TA234Nodo();
		this->hijoMeIz.raiz->itIz=aux->itDe;
		this->hijoMeIz.raiz->hijoIz.raiz=aux->hijoMeDe.raiz;
		this->hijoMeIz.raiz->hijoMeIz.raiz=aux->hijoDe.raiz;
		
		aux->hijoMeDe.raiz=aux->hijoDe.raiz=NULL;
		aux->itDe=aux->itMe=0;
		
		this->numitem=2;
		this->hijoIz.raiz->numitem=1;
		this->hijoMeIz.raiz->numitem=1;
		
		this->hijoMeIz.raiz->eshoja=this->hijoIz.raiz->eshoja;
	}
	if (num==2)
	{
		aux=this->hijoMeIz.raiz;
		
		this->itMe=aux->itMe;
		
		this->hijoMeDe.raiz=new TA234Nodo();
		this->hijoMeDe.raiz->itIz=aux->itDe;
		this->hijoMeDe.raiz->hijoIz.raiz=aux->hijoMeDe.raiz;
		this->hijoMeDe.raiz->hijoMeIz.raiz=aux->hijoDe.raiz;
	
		aux->hijoMeDe.raiz=aux->hijoDe.raiz=NULL;
		aux->itDe=aux->itMe=0;
		
		this->numitem=2;
		this->hijoMeIz.raiz->numitem=1;
		this->hijoMeDe.raiz->numitem=1;
		
		this->hijoMeDe.raiz->eshoja=this->hijoIz.raiz->eshoja;
		
	}
}


void
TA234Nodo::Divide3(const int num)
{
	TA234Nodo *aux;
	
	if (num==1)
	{
		aux=this->hijoIz.raiz;

		this->itDe=this->itMe;
		this->itMe=this->itIz;
		this->itIz=aux->itMe;
		this->hijoDe.raiz=this->hijoMeDe.raiz;
		this->hijoMeDe.raiz=this->hijoMeIz.raiz;
		
		this->hijoMeIz.raiz=new TA234Nodo;
		this->hijoMeIz.raiz->hijoIz.raiz=aux->hijoMeDe.raiz;
		this->hijoMeIz.raiz->hijoMeIz.raiz=aux->hijoDe.raiz;
		this->hijoMeIz.raiz->itIz=aux->itDe;
		
		this->hijoMeIz.raiz->eshoja=this->hijoIz.raiz->eshoja;
	}
	else if (num==2)
	{
		aux=this->hijoMeIz.raiz;

		this->itDe=this->itMe;
		this->itMe=aux->itMe;
		this->hijoDe.raiz=this->hijoMeDe.raiz;
		
		this->hijoMeDe.raiz=new TA234Nodo;
		this->hijoMeDe.raiz->hijoIz.raiz=aux->hijoMeDe.raiz;
		this->hijoMeDe.raiz->hijoMeIz.raiz=aux->hijoDe.raiz;
		this->hijoMeDe.raiz->itIz=aux->itDe;
		
		this->hijoMeDe.raiz->eshoja=this->hijoIz.raiz->eshoja;
		
	}
	else if (num==3)
	{
		aux=this->hijoMeDe.raiz;
		
		this->itDe=aux->itMe;
		
		this->hijoDe.raiz=new TA234Nodo;
		this->hijoDe.raiz->hijoIz.raiz=aux->hijoMeDe.raiz;
		this->hijoDe.raiz->hijoMeIz.raiz=aux->hijoDe.raiz;
		this->hijoDe.raiz->itIz=aux->itDe;
				
		this->hijoDe.raiz->eshoja=this->hijoIz.raiz->eshoja;
	}
	
	aux->itDe=aux->itMe=0;
	aux->hijoMeDe.raiz=aux->hijoDe.raiz=NULL;
	
	this->numitem=3;
	aux->numitem=1;
	
}

void
TA234Nodo::Combina2()
{
	TA234Nodo* Iz, *De;
	
	Iz = hijoIz.raiz;
	De = hijoMeIz.raiz;
	
	itMe = itIz;
	itIz = Iz->itIz;
	itDe = De->itIz;
	
	hijoIz.raiz = Iz->hijoIz.raiz;
	hijoMeIz.raiz = Iz->hijoMeIz.raiz;
	
	hijoMeDe.raiz = De->hijoIz.raiz;
	hijoDe.raiz = De->hijoMeIz.raiz;
	
	Iz->hijoIz.raiz = Iz->hijoMeIz.raiz = De->hijoIz.raiz = De->hijoMeIz.raiz = NULL;
	
	numitem = 3;
	eshoja = Iz->eshoja;
	
	delete Iz;
	delete De;
}

void
TA234Nodo::Reestructurar(int caso, TA234Nodo* &raiz)
{
	switch (caso)
	{
		case 1:
		{
			if(hijoMeIz.raiz->numitem == 1) //Combinar hijo iz con hijo me iz
			{
				hijoIz.raiz->itMe = itIz;
				hijoIz.raiz->itDe = hijoMeIz.raiz->itIz;
				hijoIz.raiz->hijoMeDe.raiz = hijoMeIz.raiz->hijoIz.raiz;
				hijoIz.raiz->hijoDe.raiz = hijoMeIz.raiz->hijoMeIz.raiz;
				hijoIz.raiz->numitem = 3;
				
				hijoMeIz.raiz->hijoIz.raiz = NULL;
				hijoMeIz.raiz->hijoMeIz.raiz = NULL;
				
				delete(hijoMeIz.raiz);
				
				hijoMeIz.raiz = hijoMeDe.raiz;
				hijoMeDe.raiz = hijoDe.raiz;
				hijoDe.raiz = NULL;
				itIz = itMe;
				itMe = itDe;
				numitem--;
				raiz = raiz->hijoIz.raiz;
			}
			else //Rotar hijo iz con hijo me iz
			{
				hijoIz.raiz->itMe = itIz;
				hijoIz.raiz->hijoMeDe.raiz = hijoMeIz.raiz->hijoIz.raiz;
				hijoIz.raiz->numitem ++;
				
				itIz = hijoMeIz.raiz->itIz;
				
				hijoMeIz.raiz->itIz = hijoMeIz.raiz->itMe;
				hijoMeIz.raiz->itMe = hijoMeIz.raiz->itDe;
				hijoMeIz.raiz->hijoIz.raiz = hijoMeIz.raiz->hijoMeIz.raiz;
				hijoMeIz.raiz->hijoMeIz.raiz = hijoMeIz.raiz->hijoMeDe.raiz;
				hijoMeIz.raiz->hijoMeDe.raiz = hijoMeIz.raiz->hijoDe.raiz;
				hijoMeIz.raiz->numitem--;
				hijoMeIz.raiz->hijoDe.raiz = NULL;
				raiz = raiz->hijoIz.raiz;
			}
			break;
		}
		case 2:
		{
			if (hijoIz.raiz->numitem == 1) //Combinar hijoMeIz con hijoIz
			{
				Reestructurar(1,raiz);
			}
			else if (hijoIz.raiz->numitem == 2) //Rotacion 1
			{
				hijoMeIz.raiz->itMe = hijoMeIz.raiz->itIz;
				hijoMeIz.raiz->itIz = itIz;
				hijoMeIz.raiz->hijoMeDe.raiz = hijoMeIz.raiz->hijoMeIz.raiz;
				hijoMeIz.raiz->hijoMeIz.raiz = hijoMeIz.raiz->hijoIz.raiz;					
				hijoMeIz.raiz->hijoIz.raiz = hijoIz.raiz->hijoMeDe.raiz;
				hijoMeIz.raiz->numitem++;
				
				itIz = hijoIz.raiz->itMe;
				
				hijoIz.raiz->numitem--;
				hijoIz.raiz->hijoMeDe.raiz = NULL;
				raiz = raiz->hijoMeIz.raiz;
			}
			else if (hijoIz.raiz->numitem == 3) //Rotacion 2
			{
				hijoMeIz.raiz->itMe = hijoMeIz.raiz->itIz;
				hijoMeIz.raiz->itIz = itIz;
				hijoMeIz.raiz->hijoMeDe.raiz = hijoMeIz.raiz->hijoMeIz.raiz;
				hijoMeIz.raiz->hijoMeIz.raiz = hijoMeIz.raiz->hijoIz.raiz;
				hijoMeIz.raiz->hijoIz.raiz = hijoIz.raiz->hijoDe.raiz;
				hijoMeIz.raiz->numitem++;
				
				itIz = hijoIz.raiz->itDe;
				
				hijoIz.raiz->numitem--;
				hijoIz.raiz->hijoDe.raiz = NULL;
				raiz = raiz->hijoMeIz.raiz;
			}
			
			break;
		}
		case 3:
		{
			if (hijoMeIz.raiz->numitem == 1) //Combinar
			{
				hijoMeIz.raiz->itMe = itMe;
				hijoMeIz.raiz->itDe = hijoMeDe.raiz->itIz;
				hijoMeIz.raiz->hijoMeDe.raiz = hijoMeDe.raiz->hijoIz.raiz;
				hijoMeIz.raiz->hijoDe.raiz = hijoMeDe.raiz->hijoMeIz.raiz;
				hijoMeIz.raiz->numitem = 3;
				
				hijoMeDe.raiz->hijoIz.raiz = NULL;
				hijoMeDe.raiz->hijoMeIz.raiz = NULL;
				
				delete(hijoMeDe.raiz);
				hijoMeDe.raiz = NULL;
				
				itMe = itDe;
				hijoMeDe.raiz = hijoDe.raiz;
				hijoDe.raiz = NULL;
				
				numitem--;
				raiz = raiz->hijoMeIz.raiz;
			}
			else if (hijoMeIz.raiz->numitem == 2)
			{
				hijoMeDe.raiz->itMe = hijoMeDe.raiz->itIz;
				hijoMeDe.raiz->itIz = itMe;
				hijoMeDe.raiz->hijoMeDe.raiz = hijoMeDe.raiz->hijoMeIz.raiz;
				hijoMeDe.raiz->hijoMeIz.raiz = hijoMeDe.raiz->hijoIz.raiz;
				hijoMeDe.raiz->hijoIz.raiz = hijoMeIz.raiz->hijoMeDe.raiz;
				hijoMeDe.raiz->numitem++;
				
				itMe = hijoMeIz.raiz->itMe;
				
				hijoMeIz.raiz->numitem--;
				hijoMeIz.raiz->hijoMeDe.raiz=NULL;
				raiz = raiz->hijoMeDe.raiz;
			}
			else if (hijoMeIz.raiz->numitem == 3)
			{
				hijoMeDe.raiz->itMe = hijoMeDe.raiz->itIz;
				hijoMeDe.raiz->itIz = itMe;
				hijoMeDe.raiz->hijoMeDe.raiz = hijoMeDe.raiz->hijoMeIz.raiz;
				hijoMeDe.raiz->hijoMeIz.raiz = hijoMeDe.raiz->hijoIz.raiz;
				hijoMeDe.raiz->hijoIz.raiz = hijoMeIz.raiz->hijoDe.raiz;
				hijoMeDe.raiz->numitem++;
				
				itMe = hijoMeIz.raiz->itDe;
				
				hijoMeIz.raiz->numitem--;
				hijoMeIz.raiz->hijoDe.raiz=NULL;
				raiz = raiz->hijoMeDe.raiz;
			}
			break;
		}
		case 4:
		{
			if (hijoMeDe.raiz->numitem == 1) //Combinar.
			{
				hijoMeDe.raiz->itMe = itDe;
				hijoMeDe.raiz->itDe = hijoDe.raiz->itIz;
				hijoMeDe.raiz->hijoMeDe.raiz = hijoDe.raiz->hijoIz.raiz;
				hijoMeDe.raiz->hijoDe.raiz = hijoDe.raiz->hijoMeIz.raiz;
				hijoMeDe.raiz->numitem = 3;
				
				hijoDe.raiz->hijoIz.raiz = NULL;
				hijoDe.raiz->hijoMeIz.raiz = NULL;
				
				delete (hijoDe.raiz);
				hijoDe.raiz = NULL;
				
				numitem--;
				raiz = raiz->hijoMeDe.raiz;
			}
			else if (hijoMeDe.raiz->numitem == 2) //Rotar
			{
				hijoDe.raiz->itMe = hijoDe.raiz->itIz;
				hijoDe.raiz->itIz = itDe;
				hijoDe.raiz->hijoMeDe.raiz = hijoDe.raiz->hijoMeIz.raiz;
				hijoDe.raiz->hijoMeIz.raiz = hijoDe.raiz->hijoIz.raiz;
				hijoDe.raiz->hijoIz.raiz = hijoMeDe.raiz->hijoMeDe.raiz;
				hijoDe.raiz->numitem++;
				
				itDe = hijoMeDe.raiz->itMe;
				
				hijoMeDe.raiz->numitem--;
				hijoMeDe.raiz->hijoMeDe.raiz = NULL;
				raiz = raiz->hijoDe.raiz;
			}
			else if (hijoMeDe.raiz->numitem == 3)
			{
				hijoDe.raiz->itMe = hijoDe.raiz->itIz;
				hijoDe.raiz->itIz = itDe;
				hijoDe.raiz->hijoMeDe.raiz = hijoDe.raiz->hijoMeIz.raiz;
				hijoDe.raiz->hijoMeIz.raiz = hijoDe.raiz->hijoIz.raiz;
				hijoDe.raiz->hijoIz.raiz = hijoMeDe.raiz->hijoDe.raiz;
				hijoDe.raiz->numitem++;
				
				itDe = hijoMeDe.raiz->itDe;
				
				hijoMeDe.raiz->numitem--;
				hijoMeDe.raiz->hijoDe.raiz=NULL;
				raiz = raiz->hijoDe.raiz;
			}
			break;
		}
	}
}


const TComplejo
TA234Nodo::MayorIzquierda(const int i, TComplejo b)
{
	TComplejo ret;
	if (eshoja)
	{
		if (numitem >=3)
		{
			ret = itDe;
			itDe = b;
		}
		else if (numitem >= 2)
		{
			ret = itMe;
			itMe = b;
		}
		else 
		{
			ret = itIz;
			itIz = b;
		}
	}
	else
	{
		if (i == 0)
		{
			ret = hijoIz.raiz->MayorIzquierda(3,b);
		}
		else if (i == 1 || (i>1 && numitem == 1))
		{
			ret = hijoMeIz.raiz->MayorIzquierda(3,b);
		}
		else if (i == 2 || (i>2 && numitem == 2))
		{
			ret = hijoMeDe.raiz->MayorIzquierda(3,b);
		}
		else
		{
			ret = hijoDe.raiz->MayorIzquierda(3,b);
		}
	}
	return ret;
}
	

//======================================================================

TA234Cola::~TA234Cola()
{
	if (principio != NULL) delete(principio);
}

void
TA234Cola::Encolar(const TA234Com* a)
{
	if (principio==NULL)
	{
		principio=new TA234ColaNodo((TA234Com*)a);
		fin=principio;
	}
	else
	{
		fin->sig=new TA234ColaNodo((TA234Com*)a);
		fin=fin->sig;
	}
}

TA234Com*
TA234Cola::Desencolar()
{
	TA234Com* ret = NULL;
	TA234ColaNodo *aux = NULL; 
	if (principio != NULL)
	{
		if (principio == fin)
		{
			fin = NULL;
		}
		ret = principio->n;
		aux = principio;
		principio = principio->sig;
		aux->sig=NULL;
		delete aux;
		aux = NULL;
	}
	
	return ret;
}

TA234ColaNodo::TA234ColaNodo(const TA234ColaNodo& nodo)
{ 
	n=nodo.n; 
	sig= new TA234ColaNodo(*nodo.sig);
}

TA234ColaNodo::~TA234ColaNodo()
{
	if (sig!=NULL) 
		delete(sig); 
	n=NULL;
}
